import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
def show_images(images, size=(16, 8), mode='rgb', image_type=None, grid=None, title=(None,None), fig_suptitle=None):
if not isinstance(images, tuple) and not isinstance(images, list):
images = [images]
title = [title]
if isinstance(mode, tuple) or isinstance(mode, list):
change_mode = True
else:
current_mode = mode
change_mode = False
if isinstance(image_type, tuple) or isinstance(image_type, list):
change_mode_type = True
else:
current_mode_type = image_type
change_mode_type = False
if not grid:
grid = []
grid.append(math.ceil(len(images) / 2))
grid.append(3)
fig=plt.figure(figsize=size, dpi=150)
for i, img in enumerate(images):
fig.add_subplot(grid[0], grid[1], i+1)
if change_mode:
current_mode = mode[i]
if change_mode_type:
current_mode_type = image_type[i]
if current_mode=='grayscale':
if current_mode_type=='spectrum':
plt.imshow(np.abs(img)**(0.1), cmap='gray')
else:
plt.imshow(img, cmap='gray')
else:
if current_mode_type=='spectrum':
plt.imshow(np.abs(img)**(0.1))
else:
plt.imshow(img)
if title[i] is not None:
plt.title(title[i])
plt.axis('off')
fig.suptitle(fig_suptitle, fontsize=16)
plt.show()
class ImageTransformation:
"""A set of filters and image helper functions"""
def __init__(self, image):
self.cv_img = image
self.width, self.height = image.shape
####### Helper functions #######
def count_distance(self, u, v, width, height):
return ((((u - width / 2) ** 2) +
(v - height / 2) ** 2) ** (0.5))
def calculate_spectrum(self):
fft = np.fft.fft2(self.cv_img)
fft_shift = np.fft.fftshift(fft)
return fft_shift
def mask_spectrum(self, spectrum, mask):
fshift = spectrum * mask
f_ishift = np.fft.ifftshift(fshift)
img_ifft = np.fft.ifft2(f_ishift)
return fshift, img_ifft
def normilize_image(self, image, mul_const=255.0):
np_img = np.abs(image)
return (mul_const * (np_img-np_img.min()) /
(np_img.max() - np_img.min())
).astype('int')
####### Ideal filter #######
def ideal_low_pass_filter(self, D_0):
ideal_low = np.zeros((self.height, self.width),
np.float32)
for w in range(self.width):
for h in range(self.height):
if self.count_distance(w, h, self.width, self.height) <= D_0:
ideal_low[w][h] = 1
return ideal_low
def ideal_high_pass_filter(self, D_0):
ideal_high = np.zeros((self.height, self.width),
np.float32)
for w in range(self.width):
for h in range(self.height):
if self.count_distance(w, h, self.width, self.height) > D_0:
ideal_high[w][h] = 1
return ideal_high
####### Batervort filter #######
def batervort_helper(self, w, h, width, height, D_0, n):
return 1 / (
(1 + self.count_distance(w, h, width, height) / D_0) ** (2*n)
)
def batervort_low_pass_filter(self, D_0, n):
batervort_low = np.zeros(
(self.height, self.width),
np.float32
)
for w in range(self.width):
for h in range(self.height):
batervort_low[w][h] = self.batervort_helper(
w, h, self.width,
self.height, D_0, n)
return batervort_low
def batervort_high_pass_filter(self, D_0, n):
batervort_high = np.zeros(
(self.height, self.width),
np.float32
)
for w in range(self.width):
for h in range(self.height):
batervort_high[w][h] = 1 - self.batervort_helper(w, h, self.width,
self.height, D_0, n)
return batervort_high
####### Gauss filter #######
def gauss_helper(self, x, y, width, height, d):
return math.exp((-1 * self.count_distance(x, y, width,
height) ** 2) / d)
def gauss_low_pass_filter(self, D_0):
gauss_low = np.zeros(
(self.width, self.height),
np.float32
)
for w in range(self.width):
for h in range(self.height):
d = D_0 ** 2
d *= 2
gauss_low[w][h] = self.gauss_helper(w, h, self.width,
self.height, d)
return gauss_low
def gauss_high_pass_filter(self, D_0):
gauss_high = np.zeros(
(self.width, self.height),
np.float32
)
for w in range(self.width):
for h in range(self.height):
d = D_0 ** 2
d *= 2
gauss_high[w][h] = 1 - self.gauss_helper(w, h, self.width,
self.height, d)
return gauss_high
def apply_filter(d_arr, filter_func, n_val=None):
filter_arr = []
spectrum_back_filter_arr = []
img_back_filter_arr = []
for D in d_arr:
if n_val:
filter_applied = filter_func(D, n)
else :
filter_applied = filter_func(D)
spectrum_back_filter, img_back_filter = image_transform.mask_spectrum(
spectrum, filter_applied
)
filter_arr.append(filter_applied)
spectrum_back_filter_arr.append(spectrum_back_filter)
img_back_filter_arr.append(
image_transform.normilize_image(
img_back_filter
)
)
return filter_arr, spectrum_back_filter_arr, img_back_filter_arr
def show_applied_filter3x5(images, titles, fig_suptitle, size=(16,10), grid=(3,5), mode='grayscale'):
titles = 3 * titles
image_types = 10 * ['spectrum'] + 5 * ['img']
show_images(images,
size=(16,10),
grid=(3,5),
mode='grayscale',
image_type = image_types,
title=titles,
fig_suptitle=fig_suptitle)
img = cv2.imread('image.png', 0)
image_transform = ImageTransformation(img)
spectrum = image_transform.calculate_spectrum()
show_images([img, spectrum],
mode='grayscale',
grid=(1, 3),
title=('Original image', 'Spectrum'),
image_type=(None, 'spectrum'))
filter_arr_ILPF, spectrum_back_filter_arr_ILPF, img_back_filter_arr_ILPF = apply_filter([5, 15, 30, 80, 230],
image_transform.ideal_low_pass_filter)
images = []
images = filter_arr_ILPF + spectrum_back_filter_arr_ILPF + img_back_filter_arr_ILPF
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'], fig_suptitle='Ideal Low Pass Filter')
filter_arr_IHPF, spectrum_back_filter_arr_IHPF, img_back_filter_arr_IHPF = apply_filter([5, 15, 30, 80, 230],
image_transform.ideal_high_pass_filter)
images = []
images = filter_arr_IHPF + spectrum_back_filter_arr_IHPF + img_back_filter_arr_IHPF
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'], fig_suptitle='Ideal High Pass Filter')
n_arr = [1, 2, 5, 20]
n_batervort_filter_arr = []
for n in n_arr:
filter_arr_BLPF, spectrum_back_filter_arr_BLPF, img_back_filter_arr_BLPF = apply_filter([5, 15, 30, 80, 230],
image_transform.batervort_low_pass_filter, n_val=n,)
n_batervort_filter_arr.append([filter_arr_BLPF,
spectrum_back_filter_arr_BLPF,
img_back_filter_arr_BLPF])
for i, n_batervort_filter in enumerate(n_batervort_filter_arr):
images = []
images = n_batervort_filter[0] + n_batervort_filter[1] + n_batervort_filter[2]
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'],
fig_suptitle=f"Butterword Low Pass filter\n n={n_arr[i]}")
n_arr = [1, 2, 5, 20]
n_batervort_filter_arr = []
for n in n_arr:
filter_arr_BHPF, spectrum_back_filter_arr_BHPF, img_back_filter_arr_BHPF = apply_filter([5, 15, 30, 80, 230],
image_transform.batervort_high_pass_filter, n_val=n,)
n_batervort_filter_arr.append([filter_arr_BHPF,
spectrum_back_filter_arr_BHPF,
img_back_filter_arr_BHPF])
for i, n_batervort_filter in enumerate(n_batervort_filter_arr):
images = []
images = n_batervort_filter[0] + n_batervort_filter[1] + n_batervort_filter[2]
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'],
fig_suptitle=f"Butterword High Pass filter\n n={n_arr[i]}")
filter_arr_GLPF, spectrum_back_filter_arr_GLPF, img_back_filter_arr_GLPF = apply_filter([5, 15, 30, 80, 230],
image_transform.gauss_low_pass_filter)
images = []
images = filter_arr_GLPF + spectrum_back_filter_arr_GLPF + img_back_filter_arr_GLPF
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'], fig_suptitle='Gauss Low Pass filter')
filter_arr_GHPF, spectrum_back_filter_arr_GHPF, img_back_filter_arr_GHPF = apply_filter([5, 15, 30, 80, 230],
image_transform.gauss_high_pass_filter)
images = []
images = filter_arr_GHPF + spectrum_back_filter_arr_GHPF + img_back_filter_arr_GHPF
show_applied_filter3x5(images, ['R=5','R=15','R=30','R=80','R=230'], fig_suptitle='Gauss Low Pass filter')